package com.fyy.rtspdemo.utils;

import org.bytedeco.ffmpeg.avcodec.AVCodecParameters;
import org.bytedeco.ffmpeg.avformat.AVFormatContext;
import org.bytedeco.ffmpeg.avformat.AVStream;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.FFmpegLogCallback;
import org.bytedeco.javacv.Frame;

public class VideoUtil {

    /**
     * 视频转码
     * @param inFile 原视频
     * @param outFile 输出
     */
    public static void videoConvert(String inFile,String outFile) throws Exception{
        if(outFile.indexOf(".") < 0){
            System.out.println("没有指定输出目录！");
        }
        String format = outFile.substring(outFile.lastIndexOf("."));
        FFmpegLogCallback.set();
        Frame frame;
        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inFile);
        FFmpegFrameRecorder recorder = null;

        try {
            System.out.println("开始初始化帧抓取器！");
            grabber.start(true);
            System.out.println("帧抓取器初始化完成！");

            AVFormatContext avFormatContext = grabber.getFormatContext();
            int streamNum = avFormatContext.nb_streams();

            if(streamNum < 1){
                System.out.println("不存在媒体流！");
                return;
            }
            int framerate = (int) grabber.getVideoFrameRate();
            System.out.printf("视频帧率[%d],视频时长[%d]秒,媒体流数量[%d]\r\n",framerate, avFormatContext.duration() / 1000000,
                    avFormatContext.nb_streams());

            for (int i = 0; i < streamNum; i++) {
                AVStream avStream = avFormatContext.streams(i);
                AVCodecParameters avCodecParameters = avStream.codecpar();
                System.out.printf("流的索引[%d]，编码器类型[%d]，编码器ID[%d]\r\n", i, avCodecParameters.codec_type(),
                        avCodecParameters.codec_id());
            }

            int frameWidth = grabber.getImageWidth();
            int frameHeight = grabber.getImageHeight();
            int audiochannels = grabber.getAudioChannels();

            System.out.printf("视频宽度[%d]，视频高度[%d]，音频通道数[%d]\r\n", frameWidth, frameHeight, audiochannels);

            recorder = new FFmpegFrameRecorder(outFile,frameWidth,frameHeight,audiochannels);
            recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
            recorder.setFormat(format);
            recorder.setVideoBitrate(grabber.getVideoBitrate());
            recorder.setFrameRate(framerate);
            recorder.setGopSize(framerate);
            recorder.setAudioChannels(grabber.getAudioChannels());
            recorder.start();

            int videoFramenum = 0;
            int audioframenum = 0;
            int dataframenum = 0;

            while (null != (frame = grabber.grab())){
                if(null != frame.image){
                    videoFramenum++;
                    recorder.record(frame);
                }
                if(null != frame.samples){
                    audioframenum++;
                    recorder.record(frame);
                }
                if(null != frame.data){
                    dataframenum++;
                }
                System.out.printf("转码完成，视频帧[%d]，音频帧[%d]，数据帧[%d]\r\n", videoFramenum, audioframenum, dataframenum);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(null != recorder){
                try {
                   recorder.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    grabber.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

    }

    public static void main(String[] args) {
        try {
            videoConvert("rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4","E:\\test.mp4");
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("执行完毕！");
    }

}
